package com.acce.product.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.acce.system.config.ReturnCodes;
import com.acce.system.dao.ICompanyDao;
import com.acce.system.dao.IUserDao;
import com.acce.base.pojo.ArgsPojo;
import com.acce.base.pojo.ReturnPojo;
import com.acce.product.config.ErrorCodes;
import com.acce.product.dao.IGoodsDao;
import com.acce.product.pojo.Goods;
import com.acce.product.service.GoodsService;
import com.acce.product.utils.Utils;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;

@Service("goodsService")
public class GoodsServiceImpl implements GoodsService {

	private Logger logger = Logger.getLogger(GoodsServiceImpl.class);
	
	@Resource
	IGoodsDao goodsDao;
	
	@Resource
	IUserDao userDao;
	
	@Resource
	ICompanyDao companyDao;
	
	public ReturnPojo findYXGoods(ArgsPojo args) {
		long t1 = System.currentTimeMillis();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		
		Goods goods = new Goods();
		goods.setCommodity("粤西农产品");
		goods.setValidity("1");
		goods.setCompanyDefaultState("1");
		List<Goods> list = goodsDao.getGoodsByCondition(goods);
		long t2 = System.currentTimeMillis();
		logger.info("nsy-product::generate json total spend: " + (t2-t1));
		JSONArray jsons = (JSONArray)JSONArray.toJSON(list);
		logger.info("nsy-product::findYXGoods json result");
		result.setResult(jsons);
		return result;
	}
	public ReturnPojo findGoods(ArgsPojo args) {
		long t1 = System.currentTimeMillis();
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
		String companyId = jb.getString("companyId");
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		
		Goods goods = new Goods();
		goods.setCompanyId(companyId);
		goods.setValidity("1");
		goods.setCompanyDefaultState("1");
		List<Goods> list = goodsDao.getGoodsByCondition(goods);
		long t3 = System.currentTimeMillis();
		logger.info("nsy-product::findGoodsForEmployee ..." + list.size() + "-" +(t3 -t1));
		System.out.println("nsy-product::findGoodsForEmployee ..." + list.size() + "-" +(t3 -t1));
		List<Goods> first = new ArrayList<Goods>();
		Map<String, List<Goods>> second = new HashMap<String, List<Goods>>();
		Map<String, List<Goods>> third = new HashMap<String, List<Goods>>();
		for(Goods com:list) {
			if("1".equals(com.getLevelNum())) {
				first.add(com);
			}
			
			if("2".equals(com.getLevelNum())) {
				if(second.containsKey(com.getFather())) {
					List<Goods> cs = second.get(com.getFather());
					cs.add(com);
					second.put(com.getFather(), cs);
				} else {
					List<Goods> list2 = new ArrayList<Goods>();
					list2.add(com);
					second.put(com.getFather(), list2);
				}
			}
			
			if("3".equals(com.getLevelNum())) {
				if(third.containsKey(com.getFather())) {
					List<Goods> cs = third.get(com.getFather());
					cs.add(com);
					third.put(com.getFather(), cs);
				} else {
					List<Goods> list3 = new ArrayList<Goods>();
					list3.add(com);
					third.put(com.getFather(), list3);
				}
			}
		}
		
		long t4 = System.currentTimeMillis();
		logger.info("level list spends: " + "-" +(t4 -t3));
		System.out.println("level list spends: " + "-" +(t4 -t3));
		
		JSONArray jsons = new JSONArray();
		for(Goods f1:first) {
			JSONObject j1o = (JSONObject)JSONObject.toJSON(f1);
			JSONArray j2s = new JSONArray();
			List<Goods> s2s = second.get(f1.getSon());
			if(s2s != null) {
				JSONObject j2o = null;
				for(Goods s2:s2s) {
					j2o = (JSONObject)JSONObject.toJSON(s2);
					List<Goods> t3s = third.get(s2.getSon());
					JSONArray j3s = null;
					if(t3s != null) {
						j3s = (JSONArray)JSONArray.toJSON(t3s);
						j2o.put("children", j3s);
					}
					j2s.add(j2o);
				}
				j1o.put("children", j2s);
			}
			jsons.add(j1o);
		}
		
		long t2 = System.currentTimeMillis();
		logger.info("nsy-product::generate json spend: " + (t2-t4));
		logger.info("nsy-product::generate json total spend: " + (t2-t1));
		logger.info("nsy-product::findGoodsForEmployee json result");
		result.setResult(jsons);
		return result;
	}

	@Transactional
	public ReturnPojo insertYXGoods(ArgsPojo args) {
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
		JSONObject goodsJson = jb.getJSONObject("goods");
		String currTime = Utils.getCurrTimeMillions();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		
		Goods goods = JSONObject.parseObject(goodsJson.toJSONString(), Goods.class);
		goods.setGoodsId(Utils.makeProductId());
		goods.setGoodsKingdom("粤西常用水果");
		goods.setValidity("1");
		goods.setUnit("千克");
		goods.setCompanyId("");
		goods.setCompanyName("武汉快来网络科技有限公司");
		goods.setCompanyType("system");
		goods.setSelected("0");
		goods.setSeafood("0");
		goods.setFruit("0");
		goods.setSaleSelect("0");
		goods.setBuySelect("0");
		goods.setVegetables("0");
		goods.setRawSelect("0");
		goods.setCommodity("粤西农产品");
		goods.setLevelNum("1");
		goods.setLevelExp("商品");
		goods.setProQuantity("0");
		goods.setCompanyDefaultState("1");
		goods.setEditTime(args.getEditTime());
		goods.setEditUserId(args.getEditUserId());
		goods.setSyncTime(currTime);
		goods.setSyncType("1");
		goods.setCreateTime(currTime);
		
		//查询是否已存在商品
		Goods gd = new Goods();
		gd.setCommodity("粤西农产品");
		gd.setValidity("1");
		gd.setCompanyDefaultState("1");
		gd.setSon(goods.getSon());
		List<Goods> gds = goodsDao.getGoodsByCondition(gd);
		if(gds!=null && !gds.isEmpty()) {
			logger.info("nsy-product::create goods failure, goods exist: " + gd.getSon());
			result.setReturnCode(ErrorCodes.add_goods_failure.getCode());
			result.setReturnMsg(ErrorCodes.add_goods_failure.getMessage());
			return result;
		}
		
		//get max sequenceNum
		Goods sequence = new Goods();
//		sequence.setGoodsKingdom("粤西常用水果");
		sequence.setCommodity("粤西农产品");
		sequence.setValidity("1");
		sequence.setCompanyDefaultState("1");
//		sequence.setFather("粤西常用水果");
		List<Goods> ses = goodsDao.getGoodsByCondition(sequence);
		int seq = 1;
		if(ses != null && !ses.isEmpty()) {
			//exist then return
			seq = Integer.valueOf(ses.get(0).getSequenceNum()) + 10;
		}
		logger.info("nsy-product::create goods sequenceNum: " + seq);
		goods.setSequenceNum(seq+"");
		goodsDao.insertGoods(goods);
		
		result.setResult(goods);
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		return result;
	}
	
	@Transactional
	public ReturnPojo insertGoods(ArgsPojo args) {
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
		String companyId = jb.getString("companyId");
		String companyName = jb.getString("companyName");
		String companyType = jb.getString("companyType");
		String currTime = Utils.getCurrTimeMillions();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		
		List<Goods> list = null;
		Goods goods = new Goods();
		list = goodsDao.getGoodsByCondition(goods);
		for(Goods gd:list) {
			gd.setGoodsId(Utils.makeProductId());
			gd.setCompanyId(companyId);
			gd.setCompanyName(companyName);
			gd.setCompanyType(companyType);
			gd.setValidity("1");
			gd.setCreateTime(currTime);
		}
		goodsDao.insertBatchGoods(list);
		
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		return result;
	}

	@Transactional
	public ReturnPojo updateYXGoods(ArgsPojo args) {
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
		JSONObject goodsJSON = (JSONObject)jb.get("goods");
		String currTime = Utils.getCurrTimeMillions();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		
		Goods base = JSONObject.parseObject(goodsJSON.toJSONString(), Goods.class);
		base.setValidity("0");
		base.setSyncType("1");
		base.setSyncTime(currTime);
		logger.info("nsy-product::update goods.");
		goodsDao.updateGoods(base);
		logger.info("nsy-product::update success.");
		return result;
	}
	
	@Transactional
	public ReturnPojo updateGoods(ArgsPojo args) {
		String business = args.getBusiness();
		JSONObject jb = (JSONObject)JSONObject.parse(business);
		String atUserId = jb.getString("atUserId");
		JSONObject create = (JSONObject)jb.get("create");
		JSONObject update = (JSONObject)jb.get("update");
		String currTime = Utils.getCurrTimeMillions();
		
		ReturnPojo result = new ReturnPojo();
		result.setServiceCode(args.getServiceCode());
		result.setReturnCode(ErrorCodes.oper_success.getCode());
		result.setReturnMsg(ErrorCodes.oper_success.getMessage());
		
		if(create != null) {
			Goods base = JSONObject.parseObject(create.toJSONString(), Goods.class);
			base.setGoodsId(Utils.makeProductId());
			base.setValidity("1");
			base.setSyncType("1");
			base.setSyncTime(currTime);
			base.setCreateTime(currTime);
			base.setProQuantity("0");
			base.setSelected("0");
			base.setEditUserId(atUserId);
			base.setEditTime(currTime);
			
			//check exists
			Goods check = new Goods();
			check.setCompanyId(base.getCompanyId());
			check.setGoodsKingdom(base.getGoodsKingdom());
			check.setFather(base.getFather());
			check.setSon(base.getSon());
			check.setLevelNum(base.getLevelNum());
			check.setValidity(base.getValidity());
			
			if(StringUtils.isEmpty(base.getCompanyId())
					|| StringUtils.isEmpty(base.getGoodsKingdom())
					|| StringUtils.isEmpty(base.getFather())
					|| StringUtils.isEmpty(base.getSon())
					|| StringUtils.isEmpty(base.getLevelNum())) {
				logger.info("nsy-product::create buygoods::missing args{companyId, goodsKingdom, father, son, levelNum}.");
				result.setReturnCode(ReturnCodes.PARAM_NULL.getCode());
				result.setReturnMsg(ReturnCodes.PARAM_NULL.getMessage());
				return result;
			}
			
			List<Goods> cks = goodsDao.getGoodsByCondition(check);
			if(cks != null && !cks.isEmpty()) {
				logger.info("nsy-product::create buygoods::goods name exists.");
				logger.info("nsy-product::create buygoods::create failure.");
				//exist then return
				result.setReturnCode(ErrorCodes.add_goods_failure.getCode());
				result.setReturnMsg(ErrorCodes.add_goods_failure.getMessage());
				return result;
			}
			logger.info("nsy-product::create buygoods::check over.");
			
			//get max sequenceNum
			Goods sequence = new Goods();
			sequence.setCompanyId(base.getCompanyId());
			sequence.setGoodsKingdom(base.getGoodsKingdom());
			sequence.setFather(base.getFather());
			sequence.setValidity(base.getValidity());
			List<Goods> ses = goodsDao.getGoodsByCondition(sequence);
			int seq = 1;
			if(ses != null && !ses.isEmpty()) {
				//exist then return
				seq = Integer.valueOf(ses.get(0).getSequenceNum()) + 10;
			}
			logger.info("nsy-product::create buygoods sequenceNum: " + seq);
			base.setSequenceNum(seq+"");
			
			logger.info("nsy-product::create buygoods.");
			goodsDao.insertGoods(base);
			logger.info("nsy-product::create success.");
			result.setResult(base);
			logger.info("nsy-product::result: " + JSONObject.toJSONString(base));
		}
		if(update != null) {
			Goods base = JSONObject.parseObject(update.toJSONString(), Goods.class);
			base.setValidity("1");
			base.setSyncType("1");
			base.setSyncTime(currTime);
			logger.info("nsy-product::update buygoods.");
			goodsDao.updateGoods(base);
			logger.info("nsy-product::update success.");
		}
		return result;
	}
	
}
